#include	"unp.h"
#include	"debug.h"
#include	"cli_parse.h"
#include	"readBuffer.h"
#include	"unpthread.h"

static void * sendMsg(void *arg);
static void * recvMsg(void *arg);

char requestMsg[MAXLINE];
char response[MAXLINE];
char cmdLine[MAXLINE];
ReadBuffer *rbuf;

void chat_cli(FILE *fp, int sockfd) {

	pthread_t tid1, tid2, tid3, tid4; //for chat(1,2), file transfer(3,4)
	void * thread_return;

	setDebug(0); // debug message off
	setPrompt(NULL);
	rbuf = createRbuf(MAXLINE); // ReadBuffer for response messages

	pthread_create(&tid1, NULL, sendMsg, (void *) &sockfd);
	pthread_create(&tid2, NULL, recvMsg, (void *) &sockfd);
	pthread_join(tid1, &thread_return);
	pthread_join(tid2, &thread_return);
}

static void * sendMsg(void *arg) {

	int sockfd = *((int *) arg);
	pthread_detach(pthread_self());

	for (;;) {
		printf("%s ", getPrompt()); // display prompt

		fflush(stdout);

		if (Fgets(cmdLine, MAXLINE, stdin) == NULL) { // if EoF, do not end. Wait for remaining response messages
			continue;
		}
		debug(cmdLine);
		if (cmdLine[0] == '#') // skip comment lines
			continue;
		if ((ui_parse((char *) cmdLine, requestMsg)) > 0) { // successful request message generation
			delay(3); // 3 second sleep, only if delay mode
			Writen(sockfd, requestMsg, strlen(requestMsg));
			debug("//////////////////////--> %s", requestMsg);
			if (!strcmp(cmdLine, "quit\n")){
			////end this thread
				pthread_exit(pthread_self());
			}
			//break;
		}
		else
			continue;
			// if local effective command or syntax error,
	sleep(1);
	}
	return NULL;
}

static void * recvMsg(void *arg) {
	int n, code;
	int sockfd = *((int *) arg);
	//pthread_detach(pthread_self());
	// response message arrives
	for (;;) {
		if ((n = readBuf(rbuf, sockfd)) < 0){ // read and buffer
			err_sys("read error");
		}
		if (n == 0) { // normal termination initiated by server
			close(sockfd);
		}
		while (n>0 && getMessage(rbuf, response, MAXLINE) > 0) { // get a response message
			debug("<--- %s", response);
			code = response_parse(response);
		}
		if (code == 221){ // Service closing
			close(sockfd);
			//end this thread
			//pthread_exit((void *)0);
			pthread_exit(pthread_self());
		}
		else
			continue;
		// enable reading user command
	sleep(1);
	}
	return NULL;
}

int main(int argc, char **argv) {
	int sockfd;
	struct sockaddr_storage servaddr;
	socklen_t len;

	if (argc != 3)
		err_quit("usage: chatcli <hostname/IPaddress> <service/port>");

	sockfd = Tcp_connect(argv[1], argv[2]);

	len = sizeof(servaddr);
	Getpeername(sockfd, (SA *) &servaddr, &len);
	printf("connected to %s\n", Sock_ntop_host((SA *) &servaddr, len));

	chat_cli(stdin, sockfd); /* do it all */

	exit(0);
}

